/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "ui节点库滚动视口.h"
#include "框架/工作区/节点视口/ui节点面板.h"
#include "A_引擎/文件工程/工程文件.h"
#include "A_引擎/文件工程/插件模板.h"
#include "扩展/插件.h"

#include <file_文件名数据.h>
#include <插件_节点构建.h>
#include <文件/文件.h>
#include <系统/系统平台.h>

#include "../工作区.h"



static S_库节点加载				g库模块加载信息;
static std::set<C_节点基类*>	m_Nodes;



static void on_节点库滚动视口绘制(C_Widget* self, S_2D画布* 画布) {
	C_节点库滚动视口& view = *static_cast<C_节点库滚动视口*>(self);

	//view.m_背景 = f_vg_drawConvexElement(画布, E_填充模式::e_填充面, E_图层混合模式::e_Normal);
	//view.m_字符 = f_vg_drawLineText(画布, S_UI主题::ui_默认字体, self->m_UIctx->m_文字字号);
	//
	//view.m_当前选择 = f_vg_drawConvexElement(画布, E_填充模式::e_填充线, E_图层混合模式::e_Normal);
	//view.m_图标 = f_vg_drawIco(画布, S_节点UI主题::ui_节点图标);
	//
	//view.m_焦点 = f_vg_drawConvexElement(画布, E_填充模式::e_填充面, E_图层混合模式::e_Screen);
}

static void on_节点库滚动视口布局(C_Widget* self, C_Widget** ws, uint32 num) {
	if( !num ) return;

	C_节点库滚动视口* view = static_cast<C_节点库滚动视口*>(self);
	uint32 offset = 0;

	vec2 size = view->m_项大小 + 10;
	vec2 滚动坐标 = view->m_滚动坐标;

	float32 项宽度 = view->m_项大小.x + 10;
	float32 项高度 = view->m_项大小.y + 10;

	int32 列数量 = view->m_Size.x / size.x;
	if (!列数量) return;
	int32 行数量 = view->m_项数据.size() / 列数量;
	
	f_widget_layout_V滚动钳制(view->m_滚动坐标.y, view->m_Size.y, { 行数量, 列数量 }, 项高度, view->m_项数据.size());


	uint32 y = 0;
	for (; y < 行数量; ++y) {
		for (uint32 x = 0; x < 列数量; ++x) {
			ws[offset]->f_setPos({ x * size.x + 40, y * size.y + 滚动坐标.y });
			++offset;
		}
	}

	行数量 *= 列数量;
	列数量 = view->m_项数据.size() - 行数量;
	for (uint32 x = 0; x < 列数量; ++x) {
		ws[offset]->f_setPos({ x * size.x + 40, y * size.y + 滚动坐标.y });
		++offset;
	}
}

static void on_节点库滚动视口调整(C_Widget* self) {
	C_节点库滚动视口& view = *static_cast<C_节点库滚动视口*>(self);

	auto e = self->f_get更新组件();

	f_vg_tranform(view.m_画布, {});
	//f_vg_lineText_begin(view.m_画布, view.m_字符);

	std::vector<S_2DConvexRect> 图元(e.m_Num);
	std::vector<S_GPU内存块*> 形状(e.m_Num);
	std::vector<S_2D图标> 图标(e.m_Num);

	
	bool 图标状态绘制;
	switch (f_prop_enum(((C_库视口状态条*)view.mui_状态条)->m_视口模块区)) {
		case 0: {
			图标状态绘制 = false;
			break;
		}
		case 1: {
			图标状态绘制 = true;
			break;
		}
	}


	for (uint32 i = 0; i < e.m_Num; ++i) {
		C_项面板项* item = static_cast<C_项面板项*>(e.m_W[i]);
		uint32 offset = i*2;

		vec2 pos = e.m_W[i]->m_Pos;
		vec2 size = e.m_W[i]->m_Size;
		float32 icoSize = size.y * 0.5f;


		uint32 图标着色类型 = DEF_DrawType_ICO_ColorInvert;
		uint32 面板背景色 = f_PackData4X8({ 100,100,100,100 });
		auto& itemData = item->m_项;
		if (itemData.m_DataType == 1 && itemData.m_Data) {
			S_插件* 插件 = ((S_插件*)itemData.m_Data);

			if (插件->m_库 && 图标状态绘制) {
				图标着色类型 = DEF_DrawType_ICO_Color;
				//面板背景色 = f_PackData4X8({ 100,180,140,100 });
				//面板背景色 = f_PackData4X8({ 100,140,170,100 });
				面板背景色 = f_PackData4X8({ 100, 70, 150, 100 });
			}
			else {
				图标着色类型 == DEF_ICO_Color_Monochrome;
			}
		}
		
		

		//图元[i] = {
		//	pos,
		//	size,
		//	{ S_UI主题::ui_面板圆角半径, S_UI主题::ui_面板圆角半径},
		//	{ 面板背景色, 0}
		//};

		//形状[i] = &S_2D画布::g预设_圆角矩形;
		//
		//
		//uint32 icoUV = f_vg_get图标UV(self->m_画布, view.m_图标, itemData.m_ico);
		//图标[i] = f_vg_2D图标(pos + icoSize * 0.5 + 2, icoUV, {128,128,128,255}, icoSize, 图标着色类型);
		//
		//
		//
		//f_vg_setLineText(
		//	view.m_画布, 
		//	view.m_字符, 
		//	item->m_项.m_item.front(), 
		//	{ { pos.x + 2, pos.y + size.y - 26 }, {size.x, 24} },
		//	E_对齐方式::e_据中对齐, 
		//	S_UI主题::uic_文字颜色);
		//
		//f_vg_setLineText(
		//	view.m_画布, 
		//	view.m_字符, 
		//	item->m_项.m_item.back(), 
		//	{ { pos.x + icoSize + 4, pos.y}, { size.x - icoSize, size.y - 26 } },
		//	E_对齐方式::e_左对齐, 
		//	S_UI主题::uic_文字颜色);
	}

	//f_vg_setElementRect(view.m_画布, view.m_背景, e.m_Num, 形状.data(), 图元.data());
	//f_vg_setIco(view.m_画布, view.m_图标, e.m_Num, 图标.data());


	//if (view.m_当前选择项) {
	//	形状[0] = &S_2D画布::g预设_圆角矩形;
	//	图元[0] = {
	//		view.m_当前选择项->m_Pos,
	//		view.m_当前选择项->m_Size,
	//		{S_UI主题::ui_面板圆角半径, S_UI主题::ui_面板圆角半径},
	//		{f_PackData4X8(S_UI主题::uic_菜单焦点色), 0}
	//	};
	//
	//	f_vg_setElementRect(view.m_画布, view.m_当前选择, 1, 形状.data(), 图元.data());
	//	f_vg_setLineWidth(view.m_画布, view.m_当前选择, 3);
	//}
	//else {
	//	f_vg_setElementRect(view.m_画布, view.m_当前选择, 0, 0, 0);
	//}
}

static E_事件是否传递 on_滚动视口(C_Widget* self, const S_鼠标& 鼠标) {
	C_节点库滚动视口* view = static_cast<C_节点库滚动视口*>(self);

	auto e = self->f_get更新组件();

	view->m_滚动坐标.y += 鼠标.lZ * 30;
	
	float32 项宽度 = view->m_项大小.x + 10;
	float32 项高度 = view->m_项大小.y + 10;

	int32 列数量 = view->m_Size.x / 项宽度;
	int32 行数量 = view->m_项数据.size() / 列数量;

	f_widget_layout_V滚动钳制(view->m_滚动坐标.y, view->m_Size.y, { 行数量, 列数量 }, 项高度, view->m_项数据.size());
	
	view->m_更新绘制属性 = true;
	return E_事件是否传递::e_事件传递_继续;
}

static void f_库文件_保存(FILE* f) {
	f_node后端_保存库节点(m_Nodes, f);
	m_Nodes.clear();
}

static void f_库文件_插件扩展工程(FILE* f) {
	f_node后端_保存库节点(m_Nodes, f);
	m_Nodes.clear();
}


static bool on_库视口_拖拽放下(C_Widget* self, C_Widget* 发起组件, S_拖放数据& data) {
	if (data.m_Type == E_自定义拖放数据类型::e_拖放_节点子集按钮) {
		C_节点库滚动视口* view = static_cast<C_节点库滚动视口*>(self);

		std::cout << "保存节点到库 : " << self << std::endl;
		S_插座拖放数据* 拖放数据 = (S_插座拖放数据*)(data.m_Next);
		//拖放数据->发起的节点;
		//拖放数据->发起的节点树;
		m_Nodes = { 拖放数据->发起的节点->m_NodeData };

		std::string name = 拖放数据->发起的节点->m_NodeData->f_getName();
		auto itemName = S_节点数据::g库名称分配器.f_Gen(f_str_string_to_u16(name));
		
		auto path = S_框架::m_库默认路径 / u"节点模块" / (itemName + u".node");
		
		//name = f_WStringToString(itemName);
		//std::string path = S_框架::m_库默认路径.u8string() + "节点模块/" + name + ".node";
		//path = S_框架::m_库默认路径 + name + ".node";

		f_node后端_所有节点树设置为准备保存状态();
		f_file_备份保存文件(path.string(), f_库文件_保存, S_框架::g_文件备份数量);

		f_库视口_添加节点项(view, itemName, 拖放数据->发起的节点->m_ICO);
		
	}
	return false;
}

static E_事件是否传递 on_库项_开始拖拽(C_Widget* self, const S_鼠标& 鼠标, S_拖放数据& data) {
	C_项面板项* item = static_cast<C_项面板项*>(self);
	
	auto name = item->m_项.m_item.front();

	switch (item->m_项.m_DataType) {
		case 0: {
			data.m_Type = E_自定义拖放数据类型::e_拖放_库节点模块项加载;
			g库模块加载信息.m_Path = S_框架::m_库默认路径.string() + "节点模块/" + f_str_u16_to_u8(name) + ".node";
			data.m_Next = &g库模块加载信息;
			break;
		}
		case 1: {
			//auto key = f_str_wstring_to_u16(name);
			//auto& plugin = S_框架::g_插件库[key];
			//
			//if (plugin->m_库) {
			//	data.m_Type = E_自定义拖放数据类型::e_拖放_库_插件加载;
			//	data.m_Next = &plugin->m_模块[name];
			//
			//}
			//else {
			//	data.m_Type = E_自定义拖放数据类型::e_拖放_NUL;
			//	data.m_Next = nullptr;
			//}

			break;
		}
		default:
			break;
	}

	return E_事件是否传递::e_事件传递_继续;
}

static E_事件是否传递 on_库项_拖拽(C_Widget* self, const S_鼠标& 鼠标, S_拖放数据& data) {
	//std::cout << "on_库项_拖拽 : " << 鼠标.lPos.x << std::endl;

	return E_事件是否传递::e_事件传递_继续;
}

static bool on_库项_结束拖动(C_Widget* self, C_Widget* 拾取的部件, S_拖放数据& data) {
	switch (data.m_Type) {
		case E_自定义拖放数据类型::e_拖放_节点子集按钮: {
			std::cout<<"替换库节点"<<std::endl;
			C_项面板项* item = dynamic_cast<C_项面板项*>(self);

			if (item) {
				S_插座拖放数据* 拖入的节点 = (S_插座拖放数据*)data.m_Next;
				拖入的节点->发起的节点;

				auto 老文件 = S_框架::m_库默认路径.string() + "节点模块/" + f_str_u16_to_u8(item->m_项.m_item[0]) + ".node";
				//auto 新文件名 = f_WStringToString(g名称分配器.f_Gen(拖入的节点->发起的节点->m_NodeData->f_getWName()));
				f_node后端_所有节点树设置为准备保存状态();
				f_node后端_覆盖保存库节点(老文件, { 拖入的节点->发起的节点->m_NodeData });
			}
			
			break;
		}
		default:
			break;
	}
	return true;
}

static E_事件是否传递 on_库项鼠标进入(C_Widget* self, const S_鼠标& 轮值) {
	C_节点库滚动视口& box = *static_cast<C_节点库滚动视口*>(self->m_父部件);
	C_项面板项* item = static_cast<C_项面板项*>(self);

	//S_2DConvexRect 图元 = {
	//		self->m_Pos,
	//		self->m_Size,
	//		{S_UI主题::ui_面板圆角半径, S_UI主题::ui_面板圆角半径},
	//		{f_PackData4X8({ 40,40,40, 10 }), 0}
	//};
	//S_GPU内存块* 形状 = &S_2D画布::g预设_圆角矩形;
	//
	//f_vg_setElementRect(box.m_画布, box.m_焦点, 1, &形状, &图元);

	return E_事件是否传递::e_事件传递_继续;
}

static E_事件是否传递 on_库项鼠标移出(C_Widget* self, const S_鼠标& 轮值) {
	C_节点库滚动视口& box = *static_cast<C_节点库滚动视口*>(self->m_父部件);
	C_项面板项* item = static_cast<C_项面板项*>(self);

	return E_事件是否传递::e_事件传递_继续;
}

static E_事件是否传递 on_库项点击(C_Widget* self, const E_鼠标按钮& 轮值) {
	C_节点库滚动视口& box = *static_cast<C_节点库滚动视口*>(self->m_父部件);
	C_项面板项* item = static_cast<C_项面板项*>(self);

	switch (f_prop_enum(static_cast<C_库视口状态条*>(box.mui_状态条)->m_视口模块区)) {
		case 0: {
			break;
		}
		case 1: {
			auto& name = (item->m_项.m_item.front());

			f_prop_LineStr(box.m_插件名称) = item->m_项.m_item.front();

			if (S_节点数据::g插件库.find(name) != S_节点数据::g插件库.end()) {
				f_库视口_重构插件属性栏(box.mui_属性栏, S_节点数据::g插件库[name], box);
			}
			break;
		}
	}
	
	box.m_当前选择项 = item;
	box.m_更新绘制属性 = true;
	return E_事件是否传递::e_事件传递_继续;
}

static E_事件是否传递 on_库项双击(C_Widget* self, const E_鼠标按钮& 轮值) {
	C_节点库滚动视口& box = *static_cast<C_节点库滚动视口*>(self->m_父部件);
	C_项面板项* item = static_cast<C_项面板项*>(self);


	switch (f_prop_enum(static_cast<C_库视口状态条*>(box.mui_状态条)->m_视口模块区)) {
		case 0: {
			break;
		}
		case 1: {
			auto& name = (item->m_项.m_item.front());

			if (S_节点数据::g插件库.find(name) != S_节点数据::g插件库.end()) {
				auto file = S_框架::m_扩展模块源码路径 / name / "build" / (name + u".sln");
				std::string cmd = "start ";
				cmd += file.generic_string();

				system(cmd.c_str());
			}
			break;
		}
	}


	box.m_当前选择项 = item;
	box.m_更新绘制属性 = true;
	return E_事件是否传递::e_事件传递_继续;
}

static void on_构建插件模块工程(struct S_Props& prop) {
	C_工作区页面& 页面 = *static_cast<C_工作区页面*>(prop.m_UI->m_部件->m_父部件->m_父部件->m_父部件->m_父部件);
	C_节点库滚动视口& box = *static_cast<C_节点库滚动视口*>(f_ui_get滚动框视口(页面.mui_视口页面));

	auto name = (f_prop_LineStr(box.m_插件名称));
	if (S_节点数据::g插件库.find(name) != S_节点数据::g插件库.end()) {
		
		f_插件_卸载(*S_节点数据::g插件库[name]);

		if(!S_框架::m_扩展模块源码路径.empty()) {
			S_节点数据::g插件库[name]->m_链接源码 = true;

			f_插件_构建工程(S_框架::m_扩展模块源码路径, name);
		}
	}
	box.m_更新绘制属性 = true;
	box.m_插件名称;
}

static void on_清除插件模块缓存(struct S_Props& prop) {
	C_工作区页面& 页面 = *static_cast<C_工作区页面*>(prop.m_UI->m_部件->m_父部件->m_父部件->m_父部件->m_父部件);
	C_节点库滚动视口& box = *static_cast<C_节点库滚动视口*>(f_ui_get滚动框视口(页面.mui_视口页面));

	auto name = (f_prop_LineStr(box.m_插件名称));
	if (S_节点数据::g插件库.find(name) != S_节点数据::g插件库.end()) {
		auto 插件模板路径 = S_框架::m_扩展模块源码路径 / name / (u"src/main.cpp");
		if (f_file_文件是否存在(插件模板路径)) {
			//f_file_删除文件(插件模板路径);
		}
	}
	box.m_插件名称;
}

static void on_加载插件模块(struct S_Props& prop) {
	C_工作区页面& 页面 = *static_cast<C_工作区页面*>(prop.m_UI->m_部件->m_父部件->m_父部件->m_父部件->m_父部件);
	C_节点库滚动视口& box = *static_cast<C_节点库滚动视口*>(f_ui_get滚动框视口(页面.mui_视口页面));

	auto name = (f_prop_LineStr(box.m_插件名称));
	if (f_插件_加载(*S_节点数据::g插件库[name])) {
		f_库视口_重构插件属性栏(box.mui_属性栏, S_节点数据::g插件库[name], box);
	}

}

static void on_卸载插件模块(struct S_Props& prop) {
	C_工作区页面& 页面 = *static_cast<C_工作区页面*>(prop.m_UI->m_部件->m_父部件->m_父部件->m_父部件->m_父部件);
	C_节点库滚动视口& box = *static_cast<C_节点库滚动视口*>(f_ui_get滚动框视口(页面.mui_视口页面));

	auto name = (f_prop_LineStr(box.m_插件名称));
	if (f_插件_卸载(*S_节点数据::g插件库[name])) {
		f_库视口_重构插件属性栏(box.mui_属性栏, S_节点数据::g插件库[name], box);
	}
}

static void on_插件模块_代码拷贝到剪切板(S_Props& prop) {
	f_sys_写到剪切板(f_插件模板_节点代码());
}
static void on_插件模块_变换操作代码拷贝到剪切板(S_Props& prop) {
	f_sys_写到剪切板(f_插件模板_变换操作代码());
}
static void on_插件模块_物体操作代码拷贝到剪切板(S_Props& prop) {
	//f_sys_写到剪切板(f_插件模板_变换操作代码());
}


C_节点库滚动视口::C_节点库滚动视口(S_UI渲染环境& ctx) : C_Widget(&ctx) {
	mf_绘制 = on_节点库滚动视口绘制;
	mf_布局 = on_节点库滚动视口布局;
	mf_变换 = on_节点库滚动视口调整;
	mf_鼠标滚轮 = on_滚动视口;
	mf_结束拖拽 = on_库视口_拖拽放下;

	m_项大小 = { 120, 60 };
	m_滚动坐标 = {};

	m_插件名称 = f_alloc_LineStrProp(nullptr, u"名称", u"新插件");
	m_插件名称.m_私有 = true;

	m_构建目标 = f_alloc_EnumProp(nullptr, {{u"debug"}, {u"release"}}, u"构建目标");
	m_构建目标.m_私有 = true;

	m_构建 = f_alloc_OpsProp(on_构建插件模块工程, u"构建");
	m_构建.m_私有 = true;
	m_清除 = f_alloc_OpsProp(on_清除插件模块缓存, u"清除");
	m_清除.m_私有 = true;
	m_加载插件 = f_alloc_OpsProp(on_加载插件模块, u"加载插件");
	m_加载插件.m_私有 = true;
	m_卸载插件 = f_alloc_OpsProp(on_卸载插件模块, u"卸载插件");
	m_卸载插件.m_私有 = true;


	m_节点插件代码模板 = f_alloc_OpsProp(on_插件模块_代码拷贝到剪切板, u"节点代码模板");
	m_节点插件代码模板.m_私有 = true;
	m_物体选择插件代码模板 = f_alloc_OpsProp(on_插件模块_物体操作代码拷贝到剪切板, u"物体选择模板");
	m_物体选择插件代码模板.m_私有 = true;
	m_变换操作插件代码模板 = f_alloc_OpsProp(on_插件模块_变换操作代码拷贝到剪切板, u"变换操作模板");
	m_变换操作插件代码模板.m_私有 = true;
	m_场景更新插件代码模板 = f_alloc_OpsProp(on_插件模块_物体操作代码拷贝到剪切板, u"场景更新模板");
	m_场景更新插件代码模板.m_私有 = true;

	m_当前选择项 = nullptr;

}

C_节点库滚动视口::~C_节点库滚动视口() {
	f_prop_Release(m_插件名称);
	f_prop_Release(m_构建目标);

	f_prop_Release(m_构建);
	f_prop_Release(m_清除);
	f_prop_Release(m_加载插件);

	f_prop_Release(m_节点插件代码模板);
}





static bool on_新建扩展模块(C_Widget* self, const std::vector<std::wstring>& filenames, E_对话框类型 方式) {

	f_projectFile_设置工程目录(f_str_wstring_to_u16(filenames.front()));


	
	return false;
}

static void on_库项目区切换(S_Props& prop) {
	C_工作区页面& 页面 = *static_cast<C_工作区页面*>(prop.m_UI->m_部件->m_父部件->m_父部件->m_父部件);
	C_库视口状态条* 状态条 = static_cast<C_库视口状态条*>(prop.m_UI->m_部件->m_父部件->m_父部件);

	switch (f_prop_enum(prop)) {
		case 0: {
			f_库视口_加载模块(状态条->m_View, S_框架::m_库默认路径.string() + "节点模块/");
			break;
		}
		case 1: {
			f_库视口_加载插件模块(状态条->m_View);
			break;
		}
		default:
			break;
	}

	//f_vg_setElementRect(状态条->m_View->m_画布, 状态条->m_View->m_焦点, 0, nullptr, nullptr);
	状态条->m_View->m_当前选择项 = nullptr;
	f_库视口_重构状态条(状态条);
	f_库视口_重构插件属性栏(页面.mui_属性栏, nullptr, *状态条->m_View);
}

static void on_创建插件模块(struct S_Props& prop) {
	C_库视口状态条* 状态条 = static_cast<C_库视口状态条*>(prop.m_UI->m_部件->m_父部件->m_父部件);
	
	auto 插件名称 = (f_prop_LineStr(状态条->m_创建插件初始名称));
	auto path = f_str_u16_to_u8(S_引擎配置::g_工程文件路径);
	
	if (!f_file_文件是否存在(S_引擎配置::g_工程文件名称)) {
		f_ui_打开对话框(S_节点框架::g_UIGM, S_框架::g_ui文件对话框, E_对话框类型::e_写入, on_projectFile_文件打开保存, path, u".np");
		return;
	}

	auto itemName = S_节点数据::g库名称分配器.f_Gen(插件名称);
	if (S_节点数据::g插件库.find(itemName) == S_节点数据::g插件库.end()) {
		f_插件_构建工程(path, itemName);

		auto* 插件 = new S_插件;
		插件->m_链接源码 = true;
		S_节点数据::g插件库[itemName] = 插件;

		f_库视口_添加节点项(状态条->m_View, itemName, u"ico_齿轮0000");
	}
}

C_库视口状态条::C_库视口状态条(S_UI渲染环境& ctx) : C_状态条(ctx) {
	m_View = nullptr;

	m_视口模块区 = f_alloc_EnumProp(nullptr, {
		{u"节点模块", u"节点"},
		{u"插件模块", u"connect"},
	}, u"模块区");
	m_视口模块区.m_私有 = true;
	m_视口模块区.m_UI->m_Update = on_库项目区切换;


	m_创建插件初始名称 = f_alloc_LineStrProp(nullptr, u"名称", u"新插件");
	m_创建插件初始名称.m_私有 = true;
	m_创建插件模块 = f_alloc_OpsProp(on_创建插件模块, u"创建插件");
	m_创建插件模块.m_私有 = true;

}

C_库视口状态条::~C_库视口状态条() {
	f_prop_Release(m_视口模块区);
	f_prop_Release(m_创建插件初始名称);
	f_prop_Release(m_创建插件模块);

}





C_节点库滚动视口* f_库视图_创建(S_UI渲染环境& ctx) {
	C_节点库滚动视口* view = new C_节点库滚动视口(ctx);
	C_库视口状态条* 状态条 = new C_库视口状态条(ctx);

	状态条->m_View = view;

	view->mui_属性栏 = f_创建属性边栏(ctx);
	view->mui_状态条 = 状态条;

	return view;
}

void f_库视口_添加节点项(C_节点库滚动视口* view, std::u16string name, std::u16string ico, int32 ID, void* data, uint32 type) {
	
	auto* butItem = new C_项面板项(*view->m_UIctx);
	butItem->f_setSize(view->m_项大小);

	if (ID < 0) {
		ID = view->m_项数据.size();
	}


	butItem->m_项.m_item = { name, u"说明:"};
	
	butItem->m_项.m_ico = ico;
	butItem->m_项.m_ico_color = {200,200,200,255};
	butItem->m_项.m_ID_X = ID;
	butItem->mf_开始拖拽 = on_库项_开始拖拽;
	butItem->mf_拖拽 = on_库项_拖拽;
	butItem->mf_结束拖拽 = on_库项_结束拖动;

	butItem->mf_鼠标进入 = on_库项鼠标进入;
	butItem->mf_鼠标离开 = on_库项鼠标移出;
	butItem->mf_鼠标点击 = on_库项点击;
	butItem->mf_鼠标按键双击 = on_库项双击;

	butItem->m_项.m_Data = data;
	butItem->m_项.m_DataType = 1;
	//view->f_添加子组件(butItem);
	f_widget_push待添加部件(view, butItem, -1, true);


	S_鼠标双击键位映射* 鼠标双击键位 = f_widget_alloc_鼠标双击键位映射();
	鼠标双击键位->event = f_NodeView_载入节点;
	鼠标双击键位->鼠标按键[0] = E_Input_鼠标按键::e_左键;
	鼠标双击键位->鼠标状态[0] = DEF_按键状态_按下;
	鼠标双击键位->发生组件 = butItem;
	f_ui_注册鼠标快捷键(butItem, (S_键位映射*)鼠标双击键位);

	view->m_项数据.push_back({ u"", {}, {name}, {}, (int32)ID , 0, (void*)butItem });
}

void f_库视口_加载模块(C_节点库滚动视口* view, const std::string& 目录路径) {
	S_目录文件包 文件包;
	std::vector<std::string> 扩展名过滤 = {".ex", ".bc", ".node"};
	f_file_get目录下所有文件名(目录路径, 文件包, 扩展名过滤);

	f_widget_remove区间子组件(view, 0, -1, true);
	
	for (auto& e : view->m_项数据) {
		S_节点数据::g库名称分配器.f_Move(e.m_item.front());
	}
	view->m_项数据.clear();

	//std::vector<C_Widget*> items;
	uint32 num = 文件包.文件.size();

	S_节点数据::g库名称分配器.f_Clear();
	for (uint32 i = 0; i < num; ++i) {
		auto& file = 文件包.文件[i];
		auto name = f_file_get无后缀文件名(file);
		
		S_节点数据::g库名称分配器.f_Gen(name);

		auto path = 目录路径 + f_str_u16_to_u8(file);
		auto f = fopen(path.c_str(), "rb");

		std::u16string ico_info[2];
		if (f) {
			f_node后端_加载库节点信息(ico_info, f);
			//ico = f_读取字符串(f);
			fclose(f);
		}
		f_库视口_添加节点项(view, name, ico_info[0], i);
	}
	
	view->m_更新绘制属性 = true;
}

void f_库视口_加载插件模块(C_节点库滚动视口* view) {
	
	f_widget_remove所有子部件(view, false);
	view->m_更新绘制属性 = true;

	view->m_项数据.clear();

	uint32 ID = 0;
	for (auto& k : S_节点数据::g插件库) {
		f_库视口_添加节点项(view, k.first, u"ico_齿轮0000", ID, k.second, 1);
		++ID;
	}
	return;



	//S_目录文件包 文件包;
	//std::vector<std::string> 扩展名过滤 = { ".dll", ".bc" };
	//for (auto& e : view->m_项数据) {
	//	g库名称分配器.f_Move(e.m_item.front());
	//}
	//view->m_项数据.clear();

	//uint32 num;
	//
	//f_file_get目录下所有文件名(目录路径, 文件包, 扩展名过滤);
	//num = 文件包.文件.size();
	//for (uint32 i = 0; i < num; ++i) {
	//	auto& file = 目录路径 / std::filesystem::path(文件包.文件[i]);
	//	auto name = f_file_get无后缀文件名(file.u16string());
	//
	//	if (S_框架::g_插件库.find(name) == S_框架::g_插件库.end()) {
	//		auto* 插件 = new S_插件;
	//		插件->m_Name = name;
	//		S_框架::g_插件库[name] = 插件;
	//	}
	//	
	//	if (!S_框架::g_插件库[name]->m_库 && f_插件_加载(*S_框架::g_插件库[name])) {
	//		f_库视口_添加节点项(view, name, "ico_齿轮0000", i, S_框架::g_插件库[name], 1);
	//	}
	//}
	//
	//
	//
	//文件包.文件.clear();
	//文件包.目录.clear();
	//
	//std::set<std::u16string> 当前工程插件;
	//f_file_get目录下所有目录名(S_框架::m_扩展模块源码路径.string(), 文件包);
	//
	//num = 文件包.目录.size();
	//for (uint32 i = 0; i < num; ++i) {
	//	auto& file = 文件包.目录[i];
	//	auto name = f_str_wstring_to_u16(file);
	//
	//	if (g库名称分配器.f_已存在(name) == false) {
	//
	//		if (S_框架::g_插件库.find(name) == S_框架::g_插件库.end()) {
	//			auto* 插件 = new S_插件;
	//			插件->m_Name = name;
	//			S_框架::g_插件库[name] = 插件;
	//
	//			f_库视口_添加节点项(view, name, "ico_齿轮0000", i, S_框架::g_插件库[name], 1);
	//		}
	//		else {
	//			
	//		}
	//		S_框架::g_插件库[name]->m_链接源码 = true;
	//
	//		当前工程插件.insert(name);
	//	}
	//}

	
}



void f_库视口_重构状态条(C_状态条* 状态条) {
	C_库视口状态条* bar = static_cast<C_库视口状态条*>(状态条);

	std::vector<S_Props> props;
	S_Props	prop;


	props.push_back(bar->m_视口模块区);
	props.push_back(f_alloc_NoneProp());

	switch (f_prop_enum(bar->m_视口模块区)) {
		case 0: {
			break;
		}
		case 1: {
			props.push_back(bar->m_创建插件初始名称);
			props.push_back(bar->m_创建插件模块);
			break;
		}
		default:
			break;
	}
	//prop = f_alloc_OpsProp(f_PropUpdate_返回上一级节点树, u"返回上一级");
	//props.push_back(prop);
	props.push_back(f_alloc_NoneProp());

	//props.push_back(bar->m_当前工作区节点树容器映射);
	//props.push_back(prop);

	状态条->f_构建属性部件(props, 状态条);
}

void f_库视口_重构插件属性栏(C_属性栏* plane, S_插件* 插件, C_节点库滚动视口& view) {
	std::vector<S_Props> props;

	if (插件) {
		if (插件->m_链接源码) {
			props.push_back(view.m_插件名称);
			//props.push_back(view.m_构建目标);
			props.push_back(view.m_构建);
			props.push_back(view.m_清除);
		}
		
		if (插件->m_库) {
			props.push_back(view.m_卸载插件);
		}
		else {
			props.push_back(view.m_加载插件);
		}
	}

	static auto 代码模板 = f_alloc_StrProp(nullptr, u"代码模板");
	代码模板.m_私有 = true;

	props.push_back(代码模板);

	props.push_back(view.m_节点插件代码模板);
	props.push_back(view.m_物体选择插件代码模板);
	props.push_back(view.m_变换操作插件代码模板);
	props.push_back(view.m_场景更新插件代码模板);
	//props.push_back(view.m_节点插件代码模板);
	//f_alloc_LineStrProp(&插件->m_Name, u"名称");

	plane->f_构建属性部件(props);
	view.m_更新绘制属性 = true;
}


E_事件是否传递 f_NodeView_载入节点(C_Widget* self, E_键位执行状态 状态) {
	C_项面板项* item = static_cast<C_项面板项*>(self);

	item->m_项.m_Data;
	std::cout << "f_NodeView_载入节点 : " << item->m_项.m_Data << std::endl;
	return E_事件是否传递::e_事件传递_终止;
}


